<template>
    <el-card class="list">
        <template #header>
            <div class="nav">
                <div class="title">
                    分段使用
                </div>
                <div>
                    <el-icon @click="emit('setType', 'tmp')" class="pointer">
                        <Close />
                    </el-icon>
                </div>
            </div>
        </template>
        <div>
            <el-input v-model="search" clearable placeholder="搜索目录名称" prefix-icon="Search" @input="searchChange"></el-input>
            <div class="titleList">
                <div class="titleCard" v-for="(item, index) in articleList"
                    :style="{ paddingLeft: (item.level - 1) * 14 + 'px' }" :key="index">
                    <div>
                        {{ item.content }}
                    </div>
                    <el-icon @click="emit('setEditor',item.children)" class="pointer">
                        <right />
                    </el-icon>
                </div>
            </div>
        </div>
    </el-card>
</template>

<script setup>
import { ref, onMounted, reactive } from 'vue'


const search = ref('')

const emit = defineEmits(['setType', 'setEditor'])
const articleList = ref([])
const backupList = ref([])
const generateTOC = (item = {}) => {
    const parser = new DOMParser();
    const doc = parser.parseFromString(item.doc, 'text/html');
    const bodyTagList = doc.body.querySelectorAll('h1, h2, h3, h4, h5, h6')
    let article = [];
    let surplusNode = item.doc + '<h1>';
    let oldNode = ''
    Array.from(bodyTagList).forEach((e, i) => {
        if (e.localName === 'h1') {
            let regText = `(<${e.localName}>)(.*?)(<h1>)`
            let reg = new RegExp(regText)
            oldNode = surplusNode.match(reg)[0].slice(0, -4)
            surplusNode = '<h1>' + surplusNode.replace(reg, '')
        } else {
            let regText = `(<${e.localName}>).*`
            let reg = new RegExp(regText)
            oldNode = oldNode.match(reg)[0]
        }


        let obj = {
            tag: e.localName,
            content: e.innerHTML,
            children: oldNode,
            level: Number(e.nodeName.substring(1, 2))
        }
        article.push(obj)
    })
    articleList.value = article
    backupList.value = article
}
onMounted(() => {
    generateTOC()
})

const getHeadingList = (list) => {
    if (!Array.isArray(list)) {
        return;
    }

    const reg = /h(\d)/; // 使用正则来匹配标题节点
    const levelStack = []; // 记录标题层级
    const prefixStack = []; // 记录前缀

    return list.reduce((res, node) => {
        const { tag, content } = node || {};
        const tagSplited = reg.exec(tag);
        if (!tagSplited) return res;

        updateLevelList(levelStack, prefixStack, Number(tagSplited[1]));

        res.push({
            title: `${prefixStack.join('.')} ${content}`,
            indent: prefixStack.length - 1,
        });
        return res;
    }, []);
}

const updateLevelList = (levelStack, prefixStack, current) => {
    const idx = levelStack.length - 1;
    const lastLevel = levelStack[idx];
    if (!lastLevel || current > lastLevel) {
        // 当前为最深层级，压入栈尾
        levelStack.push(current);
        prefixStack.push(1);
        return;
    }

    if (current === lastLevel) {
        // 层级相等时，只修改前缀
        prefixStack[idx]++;
    } else if (current < lastLevel) {
        // 当前层级更高，先和上一层级对比
        const preIndex = idx - 1;
        const preLevel = levelStack[preIndex];
        if (!preLevel || current > preLevel) {
            // 如果preLevel不存在，则代表当前层级比顶层更高，即 [2, 3, 1] 这种情况
            // 如果preLevel比当前层级更高，即 [1, 3, 2] 这种情况
            prefixStack[idx]++;
            levelStack[idx] = current;
        } else {
            // 删除栈尾，继续递归
            levelStack.splice(idx, 1);
            prefixStack.splice(idx, 1);
            updateLevelList(levelStack, prefixStack, current);
        }
    }
}

const searchChange = (val) => {
    console.log(backupList.value)
    articleList.value = backupList.value.filter(item => {
        return item.content.indexOf(val) !== -1
    })
}

defineExpose({
    generateTOC
})
</script>

<style lang="scss" scoped>
.list {
    width: 300px;
    margin-right: 5px;

    ::v-deep .el-card__body {
        margin-top: 5px;
        padding: 5px;
    }

    .nav {
        line-height: 32px;
        padding: 0 10px;
        display: flex;
        justify-content: space-between;
    }

    .titleList {
        margin-top: 20px;
        .titleCard {
            display: flex;
            padding: 5px;
            div {
                flex: 1;
                overflow: hidden;
                white-space: nowrap;
                text-overflow: ellipsis;
            }
            .el-icon {
                width: 50px;
            }
        }
    }
    .pointer {
        cursor: pointer;
    }
}
</style>